using System;
using System.Collections.Generic;
using System.Collections;
using System.Data;
using System.Threading;
using System.Web;
using System.Web.Services;
using System.Web.SessionState;
using TestSystem.BLL.Helpers;
using TestSystem.BLL.TestSystem;


public partial class QuizRunner : System.Web.UI.Page
{
    private static List<Test> Tests
    {
        get { return (List<Test>)_Session["Tests"]; }
    }

    public static Quiz CurrentQuiz
    {
        get { return _Session["CurrentQuiz"] as Quiz; }
    }
    
    private static Test CurrentTest
    {
        get { return (Test)_Session["CurrentTest"]; }
        set { _Session["CurrentTest"] = value; }
    }

    private static Dictionary<int, List<UserAnswer>> UserAnswers
    {
        get
        {
            return (Dictionary<int, List<UserAnswer>>)_Session["UserAnswers"];
        }
    }

    private static bool DataSaved
    {
        get { return (bool)_Session["DataSaved"]; }
        set { _Session["DataSaved"] = value; }
    }

    private static QuizHistory QuizHistory
    {
        get { return (QuizHistory) _Session["QuizHistory"]; }
    }

    private static HttpSessionState _Session
    {
        get { return HttpContext.Current.Session; }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if(_Session["TimeLeft"] == null && _Session["DataSaved"] == null && CurrentQuiz.UseTimer)
        {
            Response.Redirect("QuizResult.aspx");
        }
        if (!IsPostBack)
        {
            if (CurrentQuiz.AllowReAnswer)
            {
                testNavigation.Tests = Tests;
            }
            testNavigation.QuizID = CurrentQuiz.QuizID;
            testNavigation.UseTimer = CurrentQuiz.UseTimer;
            
            var result = UIHelper.RenderQuestionPanel(CurrentTest, null);
            questionPanel.InnerHtml = result;
        }
    }

    [WebMethod]
    public static string SubmitTest(string answered, string textAnswer, string [] answers)
    {
        _Session["Answered"] = answered;
        bool accept = false;
        if(_Session["UseTimer"] != null && !CurrentQuiz.UseTimer)
            accept = true;
        else
            accept = _Session["TimeLeft"] != null && _Session["Timer"] != null;
        if (accept)
        {
            var curTest = CurrentTest;
            switch (curTest.TestType)
            {
                case 1:
                case 2:
                    if (CheckAnswer(1, textAnswer, answers))
                        QuizHistory.Scores += curTest.Complexity;
                    break;
                case 3:
                case 4:
                    if (CheckAnswer(3, textAnswer, answers))
                        QuizHistory.Scores += curTest.Complexity;
                    break;
            }
            SaveUserAnswers(textAnswer, answers);
            if (curTest.TestID == Tests[Tests.Count - 1].TestID)
            {
                if(_Session["DataSaved"] != null)
                {
                    FinishQuiz(false);
                }
            }
            return CurrentTest == null ? "0" : (curTest.TestOrder - Tests.Count).ToString();
        }
        return "0";
    }

    [WebMethod]
    public static string GetTest(int testOrder)
    {
        bool accept = false;
        if (CurrentQuiz.UseTimer)
            accept = true;
        else
            accept = _Session["TimeLeft"] != null && _Session["Timer"] != null;
        if (accept && CurrentQuiz.AllowReAnswer)
        {
            testOrder = testOrder - 1;
            var curTest = Tests[testOrder];
            CurrentTest = curTest;
            if (UserAnswers.ContainsKey(curTest.TestID))
                return UIHelper.RenderQuestionPanel(curTest, UserAnswers[curTest.TestID]);
            return UIHelper.RenderQuestionPanel(curTest, null);
        }
        return "";
    }

    [WebMethod]
    public static string GetNextTest()
    {
        bool accept = false;
        if (!CurrentQuiz.UseTimer)
            accept = true;
        else
            accept = _Session["TimeLeft"] != null && _Session["Timer"] != null;
        if (accept && !CurrentQuiz.AllowReAnswer)
        {
            Test curTest = null;
            var count = Tests.Count;
            for (int i = 0; i < count; i++)
            {
                if (Tests[i].TestID == CurrentTest.TestID && i + 1 < count)
                {
                    curTest = Tests[i + 1];
                    break;
                }
            } 
            if (curTest != null)
            {
                CurrentTest = curTest;
                if (UserAnswers.ContainsKey(curTest.TestID))
                    return UIHelper.RenderQuestionPanel(curTest, UserAnswers[curTest.TestID]);
            }
            return UIHelper.RenderQuestionPanel(curTest, null);
        }
        return "";
    }

    private static bool CheckAnswer(int testType, string textAnswer, string []answers)
    {
        var correctAnswers = CurrentTest.CorrectAnswers;
        if (testType == 1 || testType == 2)
        {
            if (answers.Length != correctAnswers.Count)
                return false;
            foreach (var s in answers)
            {
                if (correctAnswers.Find(answer => answer.AnswerID == int.Parse(s)) == null)
                    return false;
            }
            return true;
        }
        if(testType == 3 || testType == 4)
        {
            if (textAnswer == null)
                return false;
            return correctAnswers.Find(answer => answer.Body == textAnswer) != null;
        }
        return false;
    }

    private static List<UserAnswer> GetUserAnswers(string textAnswer, string [] ans)
    {
        var answers = CurrentTest.Answers;
        var userAnswers = new List<UserAnswer>();
        if(ans.Length != 0)
        {
            foreach (var s in ans)
            {
                var tmp = answers.Find(answer => answer.AnswerID == Int32.Parse(s));
                if(tmp != null)
                    userAnswers.Add(new UserAnswer{UserAnswerID = tmp.AnswerID,
                                                   UserID = QuizHistory.UserID,
                                                   QuizID = QuizHistory.QuizID,
                                                   TestID = CurrentTest.TestID});
            }  
        }
        else if(textAnswer != null)
        {
            userAnswers.Add(new UserAnswer{UserID = QuizHistory.UserID,
                                           QuizID = QuizHistory.QuizID,
                                           TestID = CurrentTest.TestID,
                                           UserAnswerBody = textAnswer});
        }
        return userAnswers;
    }

    private static void SaveUserAnswers(string textAnswer, string [] ans)
    {
        if (textAnswer != null || ans.Length != 0)
        {
            if (UserAnswers.ContainsKey(CurrentTest.TestID))
            {
                UserAnswers.Remove(CurrentTest.TestID);
                UserAnswers.Add(CurrentTest.TestID, GetUserAnswers(textAnswer, ans));
            }
            else
                UserAnswers.Add(CurrentTest.TestID, GetUserAnswers(textAnswer, ans));
        }
    }

    private static void FinishQuiz(bool redirect)
    {
        SaveDate();
        ClearSessionVars();
        if(redirect)
        {
            HttpContext.Current.Response.Redirect("QuizResult.aspx");
        }
    }

    private static void SaveDate()
    {
        QuizHistory.DateTimeComplete = DateTime.Now;
        QuizHistory.Add(QuizHistory.QuizID, QuizHistory.UserID, QuizHistory.DateTimeStart,
                        QuizHistory.DateTimeComplete, QuizHistory.Scores);
        
        var curQuiz = Quiz.GetByQuizID(QuizHistory.QuizID);
        if (curQuiz.SaveUserAnswers)
        {
            foreach (var key in UserAnswers.Keys)
            {
                for (int i = 0; i < UserAnswers[key].Count; i++)
                {
                    UserAnswer.Add(UserAnswers[key][i].UserAnswerID, UserAnswers[key][i].UserID,
                                   QuizHistory.QuizID, key, UserAnswers[key][i].UserAnswerBody);
                }
            }
        }
    }

    private static void ClearSessionVars()
    {
        HttpContext.Current.Session["CurrentTest"] = null;
        HttpContext.Current.Session["DataSaved"] = null;
        HttpContext.Current.Session["CurrentQuiz"] = null;
    }

    protected void btnFinish_Click(object sender, EventArgs e)
    {
        FinishQuiz(true);
    }
}
